﻿using AutoMapper;
using MD5Hash;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Workflow2211A.Application.DTO;
using Workflow2211A.Application.DTO.Inputs.Workflow;
using Workflow2211A.Application.DTO.Outputs.Workflow;
using Workflow2211A.Domain;
using Workflow2211A.Domain.Entities;
using Workflow2211A.Domain.RBAC;

namespace Workflow2211A.Application.Services
{
    /// <summary>
    /// 用户实现--登录
    /// </summary>
    public class UserService:IUserService
    {
        /// <summary>
        /// 用户仓储
        /// </summary>
        private readonly IBaseRepository<UsersModel> _userRepository;
        /// <summary>
        /// AutoMapper
        /// </summary>
        private readonly IMapper _mapper;

        private readonly IConfiguration _config;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="userRepository">用户仓储</param>
        /// <param name="mapper">AutoMapper</param>
        public UserService(IBaseRepository<UsersModel> userRepository,IMapper mapper, IConfiguration configuration)
        {
            _userRepository = userRepository;
            _mapper = mapper;
            _config = configuration;
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="input">输入参数</param>
        /// <returns>返回用户信息</returns>
        public APIResult<UserOutput> Login(UserLoginInput input)
        {
            if (input == null || string.IsNullOrEmpty(input.UserName) || string.IsNullOrEmpty(input.UserPass))
            {
                return new APIResult<UserOutput>
                {
                    Code = ResultCode.Fail,
                    Message = "用户名或密码不能为空",
                };
            }

            try 
            {
                //通过手机号/邮箱/账号+密码登录(Expression)
                var pwd = input.UserPass.GetMD5();
                
                // 简化查询，直接使用SQL
                var user = _userRepository.GetAll().AsTracking()
                    .Where(u => (u.Username == input.UserName || 
                               u.Email == input.UserName || 
                               u.Phone == input.UserName) && 
                               u.Password == pwd)
                    .FirstOrDefault();
            if (user != null)
            {
                try
                {
                    //登录成功，返回Token
                    //生成令牌
                    var claims = new Claim[]
                    {
                        new Claim(ClaimTypes.Name, user.Username),
                        new Claim("Id", user.Id.ToString()),
                        new Claim("Name", user.Name ?? string.Empty)
                    };
                    //创建令牌
                    string secret = _config["Jwt:Secret"] ?? "YourDefaultSecretKey123!@#$%^&*()_+12345678";
                    string issuer = _config["Jwt:Issuer"] ?? "DefaultIssuer";
                    string audience = _config["Jwt:Audience"] ?? "DefaultAudience";
                    
                    // 确保密钥长度至少为32字节(256位)，满足HS256算法要求
                    if (secret.Length < 32)
                    {
                        secret = secret.PadRight(32, '#');
                    }
                    
                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    var token = new JwtSecurityToken(
                        issuer: issuer,
                        audience: audience,
                        claims: claims,
                        expires: DateTime.Now.AddMinutes(30),
                        signingCredentials: creds
                        );

                    return new APIResult<UserOutput>
                    {
                        Code = ResultCode.Success, // 明确设置状态码为成功(200)
                        Message = "登录成功",
                        Data = new UserOutput
                        {
                            Id = user.Id,
                            UserName = user.Username,
                            Email = user.Email ?? string.Empty,
                            Phone = user.Phone ?? string.Empty,
                            NickName = user.Name ?? string.Empty,
                            Token = new JwtSecurityTokenHandler().WriteToken(token)
                        }
                    };
                }
                catch (Exception ex)
                {
                    return new APIResult<UserOutput>
                    {
                        Code = ResultCode.Fail,
                        Message = "生成令牌失败: " + ex.Message,
                    };
                }
            }

            return new APIResult<UserOutput>
            {
                Code = ResultCode.Fail,
                Message = "用户名或密码错误",
            };
        }
        catch (Exception ex)
        {
            return new APIResult<UserOutput>
            {
                Code = ResultCode.Fail,
                Message = "登录失败: " + ex.Message,
            };
        }
        }

        public List<UserOutput> GetUser()
        {
            var users = _userRepository.GetAll().ToList();
            var userOutputs = _mapper.Map<List<UserOutput>>(users);
            return userOutputs;
        }

        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public string GenerateJwtToken(UserOutput user)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtSettings:SecretKey"]));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

            //jwt中的Playload(一般放的是用户信息)
            //Head中：算法类型

            var claims = new[]
            {
                new Claim("UserName", user.UserName),
                new Claim("NickName", user.NickName),
                new Claim("UserId", user.Id.ToString()),
                new Claim("RoleId", user.RoleId.ToString()),
                new Claim("RoleName", user.RoleName)
            };

            var token = new JwtSecurityToken(
                issuer: _config["JwtSettings:Issuer"],
                audience: _config["JwtSettings:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(120),
                signingCredentials: credentials
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}
